import io,os,re,string,sys
from lxml import etree
import re
import declare

t_gl = etree.parse('gl.xml').getroot()
t_glx = etree.parse('glx.xml').getroot()

table_file = open(declare.path+declare.table_file_name,'w')
table_fstr = ''

def get(node,value_name):
    x = node.get(value_name)
    if x != None:
        return x
    return ''

# 处理类型
for type in t_gl.findall('types/type'):
    table_fstr+=type.xpath('string(.)')
    table_fstr+='\n'
table_fstr+='\n'

# 处理enum 输出X表
enum_dict = {}
fb_dict = {}
table_fstr+='\n// enum X tables\n'
def enum_item_name(old_name):
    new_name = re.sub(r'\A[ ]*GL_','',old_name).lower()
    new_name = re.sub(r'(_bit\Z)|(_bit_)','',new_name)
    return new_name

for enums_node in t_gl.findall('enums'):
    fb = get(enums_node, 'type')
    for enum_node in enums_node.findall('enum'):
        enum = declare.Enum()
        enum.name = get(enum_node, 'name')
        enum.new_name = enum_item_name(enum.name)
        enum.value = get(enum_node, 'value')
        enum.comment = get(enum_node, 'comment')
        if enum.comment != '':
            enum.comment = '\"'+enum.comment+'\"'
        enum.group = get(enum_node, 'group').split(',')

        if fb == 'bitmask':
            enum.is_fb = 'true'
        for group in enum.group:
            if fb == 'bitmask' or group == 'PathFontStyle':
                if group not in fb_dict:
                    fb_dict[group] = []
                fb_dict[group].append(enum)
            else:
                if group not in enum_dict:
                    enum_dict[group] = []
                enum_dict[group].append(enum)

def get_enum_Xt(e_dict):
    ret = ''
    for enum_name in e_dict:
        enum_list = e_dict[enum_name]
        str = '# define Xt_' + enum_name + '(X__) \\\n'
        for enum_item in enum_list:
            str += \
                '    X__(' + \
                enum_item.value + ', ' + \
                enum_item.name + ', ' + \
                enum_item.new_name + ', ' + \
                enum_item.comment + ') \\\n'
        ret+=str + '\n'
    return ret

table_fstr += get_enum_Xt(enum_dict)
table_fstr += get_enum_Xt(fb_dict)

def get_Xt_Xt(name_, a_dict):
    ret = '#define Xt_'+name_+'(X__) \\\n'
    for item_name in a_dict:
        ret+= '    '+item_name+'(X__) \\\n'
    return ret + '\n'

table_fstr += get_Xt_Xt('enums',enum_dict)
table_fstr += get_Xt_Xt('flagbits',fb_dict)




# 处理command
table_fstr += '\n// commands\n'
ret_dict = {}
i = 0
cmd_dict = {}
cmd_list = []
for cmd_node in t_gl.findall('commands/command'):
    cmd = declare.Cmd()
    cmd.elem.append(cmd_node)
    cmd.name = cmd_node.find('proto/name').text
    cmd.ret = cmd_node.find('proto').xpath('string(.)').replace(cmd.name, '')
    v = cmd.elem[0].find('vecequiv')
    if v != None:
        cmd.vecequiv.append(v.get('name'))

    for p_node in cmd_node.findall('param'):
        p = declare.Cmd.P()
        p.node.append(p_node)

        p.name = p_node.find('name').xpath('string(.)')
        p.type = re.sub(p.name + r'\Z', '', p_node.xpath('string(.)'))
        if re.search(r'\[[0-9]+\]',p.type):
            #不完备 但是特例
            p.len = re.findall(r'\[[0-9]\]', p.type)[0].replace('[','').replace(']','')
            p.type = re.sub(p.name + r'\[[0-9]\]', '', p.type.replace(p.name, ''))
        p.group = get(p_node, 'group')
        p.len = get(p_node, 'len')

        cmd.param.append(p)


    cmd_dict[cmd.name] = cmd
    cmd_list.append(cmd.name)

# 整理宏条件
macro_api_dict = {}
macro_ext_dict = {}
for feature in t_gl.findall('feature'):
    api_name = feature.get('name')
    for cmd in feature.findall('require/command'):
        cmd_dict[cmd.get('name')].api.append(api_name)
        macro_api_dict[api_name] = get(feature,'number')

for ext in t_gl.findall('extensions/extension'):
    ext_name = ext.get('name')
    for cmd in ext.findall('require/command'):
        cmd_dict[cmd.get('name')].extensions.append(ext_name)
        macro_ext_dict[ext_name] = ''

str = '/* macro switch:\n'
for name in macro_api_dict:
    str+='# define '+name+' '+macro_api_dict[name]+'\n'
str += '*/\n'
str += '# ifdef ALL_GL_EXT\n'
for name in macro_ext_dict:
    str+='    # define '+name+'\n'
str += '# endif\n'
table_fstr = str + table_fstr

cmd_list.sort()
str = ''
for name in cmd_list:
    node = cmd_dict[name]

    api_str = ''
    first = True
    for api in node.api:
        if first == True:
            first = False
        else:
            api_str+=' || '
        api_str+='defined('+api+')'
    if api_str != '':
        api_str = '('+api_str+')'

    ext_str = ''
    first = True
    for ext in node.extensions:
        if first == True:
            first = False
        else:
            ext_str+=' || '
        ext_str+='defined('+ext+')'
    if ext_str != '':
        ext_str = '('+ext_str+')'

    if api_str!='' or ext_str!='':
        node.pq += '# if '
        node.pq += api_str
        if api_str!='' and ext_str!='':
            node.pq += '&&'
        node.pq+=ext_str
    #print(node.pq)

# 输出类型声明
for cmd_name in cmd_list:
    cmd = cmd_dict[cmd_name]
    str = ''

    str += cmd.ret + cmd.name+'('
    first = True
    for param in cmd.param:
        line = ''
        if first == True:
            first = False
        else:
            line += ','
        line += '\n    '+param.node[0].xpath('string(.)')
        if len(param.len)!= 0 or len(param.group) != 0:
            while len(line)<=32:
                line+=' '
            line += '/* '
            if len(param.len) != 0:
                line += 'len['+param.len+']'
                if len(param.group) != 0:
                    line += ' '
            if len(param.group) != 0:
                line += 'group[' + param.group + ']'
            line += ' */'
        str += line
    if first == False:
        str += '\n'
    str += ');'
    str = 'using PFN_' + cmd.name + ' = ' + str.replace(cmd.name, '(*)')
    table_fstr += str+'\n'

# 输出X表项
table_fstr += '\n//commands name macro\n'
for cmd_name in cmd_list:
    cmd = cmd_dict[cmd_name]
    str = cmd.pq
    str += '\n    # define Xti_'+cmd.name+'(X__) X__('+\
            cmd.name+', ' + \
            cmd.ret+', '
    if cmd.alias != '':
        str += '\"'+cmd.alias+'\"'
    str+=', '
    if len(cmd.vecequiv) != 0:
        str += '\"'
        first = True
        for v in cmd.vecequiv:
            if first == True:
                first = False
            else:
                str+=' | '
            str += v
        if len(cmd.vecequiv) != 0:
            str += '\"'
    str += ')\n'
    if cmd.pq != '':
        str += '# else\n' \
               '    # define Xti_'+cmd.name+'(X__) \n' \
               '# endif\n'
    table_fstr += str

table_fstr += '\n//all commands name X table\n'
str = '# define Xt_all_og_cmds_with_pq(X__) \\\n'
for cmd_name in cmd_list:
    str+='    Xti_'+cmd_name+'(X__) \\\n'

table_fstr += str

table_file.write(table_fstr)
table_file.close()



















